package crazymakercircle;

import com.google.common.util.concurrent.*;
import org.checkerframework.checker.nullness.qual.Nullable;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @Author: DRevelation
 * @Date: 2021/7/26 15:59
 */
public class GuavaFutureDemo {

    public static final int SLEEP_GAP = 3000;

    static class HotWaterJob implements Callable<Boolean> {

        @Override
        public Boolean call() throws Exception {
            try {
                System.out.println("洗好水壶");
                System.out.println("烧开水");
                Thread.sleep(SLEEP_GAP);
                System.out.println("水开了");
            } catch (Exception e) {
                System.out.println("烧水工作发生异常被中断");
                return false;
            }
            System.out.println("烧水工作，运行结束");
            return true;
        }
    }

    static class WashJob implements Callable<Boolean> {

        @Override
        public Boolean call() throws Exception {
            try {
                System.out.println("洗茶杯");
                Thread.sleep(SLEEP_GAP);
                System.out.println("洗完了");
            } catch (Exception e) {
                System.out.println("清洗工作发生异常被中断");
                return false;
            }
            System.out.println("清洗工作，运行结束");
            return true;
        }
    }

    static class DrinkJob {
        boolean waterOK = false;
        boolean cupOK = false;

        public void drinkTea() {
            if (waterOK && cupOK) {
                System.out.println("泡茶喝，茶喝完");
                this.waterOK = false;
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
        Thread.currentThread().setName("泡茶喝线程");
        DrinkJob drinkJob = new DrinkJob();
        Callable<Boolean> hotWaterJob = new HotWaterJob();
        Callable<Boolean> washJob = new WashJob();

        ExecutorService exec = Executors.newFixedThreadPool(10);
        //构造guava线程池
        ListeningExecutorService gPool = MoreExecutors.listeningDecorator(exec);
        //烧水的回调钩子
        FutureCallback<Boolean> hotWaterHook = new FutureCallback<Boolean>() {

            @Override
            public void onSuccess(@Nullable Boolean result) {
                if (result) {
                    drinkJob.waterOK = true;
                    drinkJob.drinkTea();
                }
            }

            @Override
            public void onFailure(Throwable t) {
                System.out.println("烧水失败，没有茶喝了");
            }
        };
        //启动烧水线程
        ListenableFuture<Boolean> hotFuture = gPool.submit(hotWaterJob);
        //设置烧水线程的回调钩子
        Futures.addCallback(hotFuture, hotWaterHook, Executors.newSingleThreadExecutor());

        ListenableFuture<Boolean> washFuture = gPool.submit(washJob);
        Futures.addCallback(washFuture, new FutureCallback<Boolean>() {

            @Override
            public void onSuccess(@Nullable Boolean result) {
                if (result) {
                    drinkJob.cupOK = true;
                    drinkJob.drinkTea();
                }
            }

            @Override
            public void onFailure(Throwable t) {
                System.out.println("杯子洗不了，没有茶喝了");
            }
        }, Executors.newSingleThreadExecutor());
        System.out.println("干点其他事");
        Thread.sleep(1000);
        System.out.println("执行完成");
    }
}
